home *** CD-ROM | disk | FTP | other *** search
/ Young Minds / Young Minds Interactive CD-ROM.ISO / backgamm / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-03-09  |  11.3 KB  |  571 lines

  1. /*
  2.  * Copyright (c) 1980 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that this notice is preserved and that due credit is given
  7.  * to the University of California at Berkeley. The name of the University
  8.  * may not be used to endorse or promote products derived from this
  9.  * software without specific prior written permission. This software
  10.  * is provided ``as is'' without express or implied warranty.
  11.  */
  12.  
  13. #ifndef lint
  14. char copyright[] =
  15. "@(#) Copyright (c) 1980 Regents of the University of California.\n\
  16.  All rights reserved.\n";
  17. #endif /* not lint */
  18.  
  19. #ifndef lint
  20. static char sccsid[] = "@(#)main.c    5.4 (Berkeley) 2/16/88";
  21. #endif /* not lint */
  22.  
  23. #include <stdio.h>
  24. #include "back.h"
  25.  
  26. #define MVPAUSE    5                /* time to sleep when stuck */
  27. #define MAXUSERS 35                /* maximum number of users */
  28.  
  29. char    *instr[];                /* text of instructions */
  30. char    *message[];                /* update message */
  31. char    ospeed;                    /* tty output speed */
  32.  
  33. char    *helpm[] = {                /* help message */
  34.     "Enter a space or newline to roll, or",
  35.     "     R   to reprint the board\tD   to double",
  36.     "     S   to save the game\tQ   to quit",
  37.     0
  38. };
  39.  
  40. char    *contin[] = {                /* pause message */
  41.     "(Type a newline to continue.)",
  42.     "",
  43.     0
  44. };
  45.  
  46. static char user1a[] =
  47.     "Sorry, you cannot play backgammon when there are more than ";
  48. static char user1b[] =
  49.     " users\non the system.";
  50. static char user2a[] =
  51.     "\nThere are now more than ";
  52. static char user2b[] =
  53.     " users on the system, so you cannot play\nanother game.  ";
  54. static char    rules[] = "\nDo you want the rules of the game?";
  55. static char    noteach[] = "Teachgammon not available!\n\007";
  56. static char    need[] = "Do you need instructions for this program?";
  57. static char    askcol[] =
  58.     "Enter 'r' to play red, 'w' to play white, 'b' to play both:";
  59. static char    rollr[] = "Red rolls a ";
  60. static char    rollw[] = ".  White rolls a ";
  61. static char    rstart[] = ".  Red starts.\n";
  62. static char    wstart[] = ".  White starts.\n";
  63. static char    toobad1[] = "Too bad, ";
  64. static char    unable[] = " is unable to use that roll.\n";
  65. static char    toobad2[] = ".  Too bad, ";
  66. static char    cantmv[] = " can't move.\n";
  67. static char    bgammon[] = "Backgammon!  ";
  68. static char    gammon[] = "Gammon!  ";
  69. static char    again[] = ".\nWould you like to play again?";
  70. static char    svpromt[] = "Would you like to save this game?";
  71.  
  72. static char    password[] = "losfurng";
  73. static char    pbuf[10];
  74.  
  75. main (argc,argv)
  76. int    argc;
  77. char    **argv;
  78.  
  79. {
  80.     register int    i;        /* non-descript index */
  81.     register int    l;        /* non-descript index */
  82.     register char    c;        /* non-descript character storage */
  83.     long    t;            /* time for random num generator */
  84.  
  85.     /* initialization */
  86.     bflag = 2;                    /* default no board */
  87.     signal (2,getout);                /* trap interrupts */
  88.     if (gtty (0,&tty) == -1)            /* get old tty mode */
  89.         errexit ("backgammon(gtty)");
  90.     old = tty.sg_flags;
  91. #ifdef V7
  92.     raw = ((noech = old & ~ECHO) | CBREAK);        /* set up modes */
  93. #else
  94.     raw = ((noech = old & ~ECHO) | RAW);        /* set up modes */
  95. #endif
  96.     ospeed = tty.sg_ospeed;                /* for termlib */
  97.  
  98.                             /* check user count */
  99. # ifdef CORY
  100.     if (ucount() > MAXUSERS)  {
  101.         writel (user1a);
  102.         wrint (MAXUSERS);
  103.         writel (user1b);
  104.         getout();
  105.     }
  106. # endif
  107.  
  108.                             /* get terminal
  109.                              * capabilities, and
  110.                                 * decide if it can
  111.                              * cursor address */
  112.     tflag = getcaps (getenv ("TERM"));
  113.                             /* use whole screen
  114.                              * for text */
  115.     if (tflag)
  116.         begscr = 0;
  117.     t = time(0);
  118.     srandom(t);                    /* 'random' seed */
  119.  
  120. #ifdef V7
  121.     while (*++argv != 0)                /* process arguments */
  122. #else
  123.     while (*++argv != -1)                /* process arguments */
  124. #endif
  125.         getarg (&argv);
  126.     args[acnt] = '\0';
  127.     if (tflag)  {                    /* clear screen */
  128.         noech &= ~(CRMOD|XTABS);
  129.         raw &= ~(CRMOD|XTABS);
  130.         clear();
  131.     }
  132.     fixtty (raw);                    /* go into raw mode */
  133.  
  134.                             /* check if restored
  135.                              * game and save flag
  136.                              * for later */
  137.     if (rfl = rflag)  {
  138.         text (message);                /* print message */
  139.         text (contin);
  140.         wrboard();                /* print board */
  141.                             /* if new game, pretend
  142.                              * to be a non-restored
  143.                              * game */
  144.         if (cturn == 0)
  145.             rflag = 0;
  146.     } else  {
  147.         rscore = wscore = 0;            /* zero score */
  148.         text (message);                /* update message
  149.                              * without pausing */
  150.  
  151.         if (aflag)  {                /* print rules */
  152.             writel (rules);
  153.             if (yorn(0))  {
  154.  
  155.                 fixtty (old);        /* restore tty */
  156.                 execl (TEACH,"teachgammon",args,0);
  157.  
  158.                 tflag = 0;        /* error! */
  159.                 writel (noteach);
  160.                 exit();
  161.             } else  {            /* if not rules, then
  162.                              * instructions */
  163.                 writel (need);
  164.                 if (yorn(0))  {        /* print instructions */
  165.                     clear();
  166.                     text (instr);
  167.                 }
  168.             }
  169.         }
  170.  
  171.         init();                    /* initialize board */
  172.  
  173.         if (pnum == 2)  {            /* ask for color(s) */
  174.             writec ('\n');
  175.             writel (askcol);
  176.             while (pnum == 2)  {
  177.                 c = readc();
  178.                 switch (c)  {
  179.  
  180.                 case 'R':        /* red */
  181.                     pnum = -1;
  182.                     break;
  183.  
  184.                 case 'W':        /* white */
  185.                     pnum = 1;
  186.                     break;
  187.  
  188.                 case 'B':        /* both */
  189.                     pnum = 0;
  190.                     break;
  191.  
  192.                 case 'P':
  193.                     if (iroll)
  194.                         break;
  195.                     if (tflag)
  196.                         curmove (curr,0);
  197.                     else
  198.                         writec ('\n');
  199.                     writel ("Password:");
  200.                     signal (14,getout);
  201.                     cflag = 1;
  202.                     alarm (10);
  203.                     for (i = 0; i < 10; i++)  {
  204.                         pbuf[i] = readc();
  205.                         if (pbuf[i] == '\n')
  206.                             break;
  207.                     }
  208.                     if (i == 10)
  209.                         while (readc() != '\n');
  210.                     alarm (0);
  211.                     cflag = 0;
  212.                     if (i < 10)
  213.                         pbuf[i] = '\0';
  214.                     for (i = 0; i < 9; i++)
  215.                         if (pbuf[i] != password[i])
  216.                             getout();
  217.                     iroll = 1;
  218.                     if (tflag)
  219.                         curmove (curr,0);
  220.                     else
  221.                         writec ('\n');
  222.                     writel (askcol);
  223.                     break;
  224.  
  225.                 default:        /* error */
  226.                     writec ('\007');
  227.                 }
  228.             }
  229.         } else  if (!aflag)
  230.                             /* pause to read
  231.                              * message */
  232.             text (contin);
  233.  
  234.         wrboard();                /* print board */
  235.  
  236.         if (tflag)
  237.             curmove (18,0);
  238.         else
  239.             writec ('\n');
  240.     }
  241.                             /* limit text to bottom
  242.                              * of screen */
  243.     if (tflag)
  244.         begscr = 17;
  245.  
  246.     for (;;)  {                    /* begin game! */
  247.                             /* initial roll if
  248.                              * needed */
  249.         if ((! rflag) || raflag)
  250.             roll();
  251.  
  252.                             /* perform ritual of
  253.                              * first roll */
  254.         if (! rflag)  {
  255.             if (tflag)
  256.                 curmove (17,0);
  257.             while (D0 == D1)        /* no doubles */
  258.                 roll();
  259.  
  260.                             /* print rolls */
  261.             writel (rollr);
  262.             writec (D0+'0');
  263.             writel (rollw);
  264.             writec (D1+'0');
  265.  
  266.                             /* winner goes first */
  267.             if (D0 > D1)  {
  268.                 writel (rstart);
  269.                 cturn = 1;
  270.             } else  {
  271.                 writel (wstart);
  272.                 cturn = -1;
  273.             }
  274.         }
  275.  
  276.                             /* initalize variables
  277.                              * according to whose
  278.                              * turn it is */
  279.  
  280.         if (cturn == 1)  {                /* red */
  281.             home = 25;
  282.             bar = 0;
  283.             inptr = &in[1];
  284.             inopp = &in[0];
  285.             offptr = &off[1];
  286.             offopp = &off[0];
  287.             Colorptr = &color[1];
  288.             colorptr = &color[3];
  289.             colen = 3;
  290.         } else  {                    /* white */
  291.             home = 0;
  292.             bar = 25;
  293.             inptr = &in[0];
  294.             inopp = &in[1];
  295.             offptr = &off[0];
  296.             offopp = &off[1];
  297.             Colorptr = &color[0];
  298.             colorptr = &color[2];
  299.             colen = 5;
  300.         }
  301.  
  302.                             /* do first move
  303.                              * (special case) */
  304.         if (! (rflag && raflag))  {
  305.             if (cturn == pnum)        /* computer's move */
  306.                 move (0);
  307.             else  {                /* player's move */
  308.                 mvlim = movallow();
  309.                             /* reprint roll */
  310.                 if (tflag)
  311.                     curmove (cturn == -1? 18: 19,0);
  312.                 proll();
  313.                 getmove();        /* get player's move */
  314.             }
  315.         }
  316.         if (tflag)  {
  317.             curmove (17,0);
  318.             cline();
  319.             begscr = 18;
  320.         }
  321.  
  322.                             /* no longer any diff-
  323.                              * erence between normal
  324.                              * game and recovered
  325.                              * game. */
  326.         rflag = 0;
  327.  
  328.                             /* move as long as it's
  329.                              * someone's turn */
  330.         while (cturn == 1 || cturn == -1)  {
  331.  
  332.                             /* board maintainence */
  333.             if (tflag)
  334.                 refresh();        /* fix board */
  335.             else
  336.                             /* redo board if -p */
  337.                 if (cturn == bflag || bflag == 0)
  338.                     wrboard();
  339.  
  340.                             /* do computer's move */
  341.             if (cturn == pnum)  {
  342.                 move (1);
  343.  
  344.                             /* see if double
  345.                              * refused */
  346.                 if (cturn == -2 || cturn == 2)
  347.                     break;
  348.  
  349.                             /* check for winning
  350.                              * move */
  351.                 if (*offopp == 15)  {
  352.                     cturn *= -2;
  353.                     break;
  354.                 }
  355.                 continue;
  356.  
  357.             }
  358.  
  359.                             /* (player's move) */
  360.  
  361.                             /* clean screen if
  362.                              * safe */
  363.             if (tflag && hflag)  {
  364.                 curmove (20,0);
  365.                 clend ();
  366.                 hflag = 1;
  367.             }
  368.  
  369.                             /* if allowed, give him
  370.                              * a chance to double */
  371.             if (dlast != cturn && gvalue < 64)  {
  372.                 if (tflag)
  373.                     curmove (cturn == -1? 18: 19,0);
  374.                 writel (*Colorptr);
  375.                 c = readc();
  376.  
  377.                             /* character cases */
  378.                 switch (c)  {
  379.  
  380.                             /* reprint board */
  381.                 case 'R':
  382.                     wrboard();
  383.                     break;
  384.  
  385.                             /* save game */
  386.                 case 'S':
  387.                     raflag = 1;
  388.                     save (1);
  389.                     break;
  390.  
  391.                             /* quit */
  392.                 case 'Q':
  393.                     quit();
  394.                     break;
  395.  
  396.                             /* double */
  397.                 case 'D':
  398.                     dble();
  399.                     break;
  400.  
  401.                             /* roll */
  402.                 case ' ':
  403.                 case '\n':
  404.                     roll();
  405.                     writel (" rolls ");
  406.                     writec (D0+'0');
  407.                     writec (' ');
  408.                     writec (D1+'0');
  409.                     writel (".  ");
  410.  
  411.                             /* see if he can move */
  412.                     if ( (mvlim = movallow()) == 0)  {
  413.  
  414.                             /* can't move */
  415.                         writel (toobad1);
  416.                         writel (*colorptr);
  417.                         writel (unable);
  418.                         if (tflag)  {
  419.                             if (pnum)  {
  420.                                 buflush();
  421.                                 sleep (MVPAUSE);
  422.                             }
  423.                         }
  424.                         nexturn();
  425.                         break;
  426.                     }
  427.  
  428.                             /* get move */
  429.                     getmove();
  430.  
  431.                             /* okay to clean
  432.                              * screen */
  433.                     hflag = 1;
  434.                     break;
  435.  
  436.                             /* invalid character */
  437.                 default:
  438.  
  439.                             /* print help message */
  440.                     if (tflag)
  441.                         curmove (20,0);
  442.                     else
  443.                         writec ('\n');
  444.                     text (helpm);
  445.                     if (tflag)
  446.                         curmove (cturn == -1? 18: 19,0);
  447.                     else
  448.                         writec ('\n');
  449.  
  450.                             /* don't erase */
  451.                     hflag = 0;
  452.                 }
  453.             } else  {            /* couldn't double */
  454.  
  455.                             /* print roll */
  456.                 roll();
  457.                 if (tflag)
  458.                     curmove (cturn == -1? 18: 19,0);
  459.                 proll ();
  460.  
  461.                             /* can he move? */
  462.                 if ((mvlim = movallow()) == 0)  {
  463.  
  464.                             /* he can't */
  465.                     writel (toobad2);
  466.                     writel (*colorptr);
  467.                     writel (cantmv);
  468.                     buflush();
  469.                     sleep (MVPAUSE);
  470.                     nexturn();
  471.                     continue;
  472.                 }
  473.  
  474.                             /* get move */
  475.                 getmove();
  476.             }
  477.         }
  478.  
  479.                             /* don't worry about who
  480.                              * won if quit */
  481.         if (cturn == 0)
  482.             break;
  483.  
  484.                             /* fix cturn = winner */
  485.         cturn /= -2;
  486.  
  487.                             /* final board pos. */
  488.         if (tflag)
  489.             refresh();
  490.  
  491.                             /* backgammon? */
  492.         mflag = 0;
  493.         l = bar+7*cturn;
  494.         for (i = bar; i != l; i += cturn)
  495.             if (board[i]*cturn)  mflag++;
  496.  
  497.                             /* compute game value */
  498.         if (tflag)
  499.             curmove (20,0);
  500.         if (*offopp == 15)  {
  501.             if (mflag)  {
  502.                 writel (bgammon);
  503.                 gvalue *= 3;
  504.             }
  505.             else  if (*offptr <= 0)  {
  506.                 writel (gammon);
  507.                 gvalue *= 2;
  508.             }
  509.         }
  510.  
  511.                             /* report situation */
  512.         if (cturn == -1)  {
  513.             writel ("Red wins ");
  514.             rscore += gvalue;
  515.         } else {
  516.             writel ("White wins ");
  517.             wscore += gvalue;
  518.         }
  519.         wrint (gvalue);
  520.         writel (" point");
  521.         if (gvalue > 1)
  522.             writec ('s');
  523.         writel (".\n");
  524.  
  525.                             /* write score */
  526.         wrscore();
  527.  
  528.                             /* check user count */
  529. # ifdef CORY
  530.         if (ucount() > MAXUSERS)  {
  531.             writel (user2a);
  532.             wrint (MAXUSERS);
  533.             writel (user2b);
  534.             rfl = 1;
  535.             break;
  536.         }
  537. # endif
  538.  
  539.                             /* see if he wants
  540.                              * another game */
  541.         writel (again);
  542.         if ((i = yorn ('S')) == 0)
  543.             break;
  544.  
  545.         init();
  546.         if (i == 2)  {
  547.             writel ("  Save.\n");
  548.             cturn = 0;
  549.             save (0);
  550.         }
  551.  
  552.                             /* yes, reset game */
  553.         wrboard();
  554.     }
  555.  
  556.     /* give him a chance to save if game was recovered */
  557.     if (rfl && cturn)  {
  558.         writel (svpromt);
  559.         if (yorn (0))  {
  560.                             /* re-initialize for
  561.                              * recovery */
  562.             init();
  563.             cturn = 0;
  564.             save(0);
  565.         }
  566.     }
  567.  
  568.                             /* leave peacefully */
  569.     getout ();
  570. }
  571.